package org.jeecg.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.entity.UserInfoEntity;
import org.jeecg.modules.system.mapper.SysDepartMapper;
import org.jeecg.modules.system.mapper.SysUserDepartMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.jeecg.modules.system.mapper.UserInfoMapper;
import org.jeecg.modules.system.service.IStatisticsService;
import org.jeecg.modules.system.vo.NameValueVo;
import org.jeecg.modules.system.vo.OrgColumnVo;
import org.jeecg.modules.system.vo.SysStatisticsVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yaojia
 * @since 2024-08-07 09:18
 **/
@Service
public class StatisticsServiceImpl implements IStatisticsService {


    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    SysUserDepartMapper sysUserDepartMapper;
    @Resource
    SysDepartMapper sysDepartMapper;

    @Resource
    UserInfoMapper userInfoMapper;

    /**
     * 统计各公司内设机构学历
     *
     * @param depId
     * @return: java.util.List<org.jeecg.modules.system.vo.NameValueVo>
     * @Author: yinhm
     * @Date: 2024-08-23 09:16
     */
    public List<NameValueVo> queryFullTimeEducationCount(String depId) {
        LambdaQueryWrapper<SysUserDepart> querySysUserDepart = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(depId)) {
            // 只取当前部门id的下级部门id
            List<SysDepart> sysDeparts = sysDepartMapper.queryDeptByPid(depId);
            List<String> depIdList = sysDeparts.stream().map(SysDepart::getId).collect(Collectors.toList());
            depIdList.add(depId);
            querySysUserDepart.in(SysUserDepart::getDepId, depId);
        }
        List<SysUserDepart> sysUserDepartList = sysUserDepartMapper.selectList(querySysUserDepart);

        // 全部可用用户
        LambdaQueryWrapper<SysUser> queryUserList = new LambdaQueryWrapper<>();
        queryUserList.eq(SysUser::getDelFlag, "0").select(SysUser::getId);
        List<String> sysUserIdList = sysUserMapper.selectList(queryUserList).stream().map(SysUser::getId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(sysUserIdList)) {
            return null;
        }

        // 过滤后的用户Id
        List<String> filteredUserIdList = sysUserDepartList.stream()
                .filter(depart -> sysUserIdList.contains(depart.getUserId()))
                .map(SysUserDepart::getUserId)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(filteredUserIdList)) {
            return null;
        }
        LambdaQueryWrapper<UserInfoEntity> queryUserInfoCount = new LambdaQueryWrapper<>();
        queryUserInfoCount.in(UserInfoEntity::getUserId, filteredUserIdList);
        List<UserInfoEntity> userInfoEntities = userInfoMapper.selectList(queryUserInfoCount);

        Map<String, Long> fullTimeEducationCountMap = userInfoEntities.stream()
                .collect(Collectors.groupingBy(UserInfoEntity::getFullTimeEducation, Collectors.counting()));

        List<NameValueVo> educationCountList = fullTimeEducationCountMap.entrySet().stream()
                .map(entry -> new NameValueVo(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
        return educationCountList;
    }


    @Override
    public SysStatisticsVO indexStats(String depId) {

        SysStatisticsVO sysStatisticsVO = new SysStatisticsVO();

        //List<SysDepart> sysDepartsList = this.queryOrgDepart(depId);

        List<SysDepart> sysDepartsList = this.queryCurrentAndChildByDepId(depId);

        Map<String, SysDepart> departMap = sysDepartsList.stream().collect(Collectors.toMap(SysDepart::getId, Function.identity()));
        // 企业员额制定人数
        Integer departCount = sysDepartsList.stream()
                .map(SysDepart::getMember)
                .filter(Objects::nonNull).mapToInt(Integer::intValue).sum();
        sysStatisticsVO.setMemberCount(departCount);

        List<String> depIdList = sysDepartsList.stream().map(SysDepart::getId).collect(Collectors.toList());
        // 在职、占职数的部门人员
        List<SysUserDepart> sysUserDeparts = this.querySysUserDepartList(depId, depIdList);

        // 每个部门人数
        Map<String, Integer> depIdCountMap = sysUserDeparts.stream()
                .collect(Collectors.groupingBy(SysUserDepart::getDepId, Collectors.summingInt(e -> 1)));
        Map<String, Integer> parentDepIdCountMap = new HashMap<>();

        List<OrgColumnVo> orgColumnVoList = new ArrayList<>();
        if (StringUtils.isBlank(depId)) {
            // 当前部门对应的公司
            Map<String, String> childToParentDepIdMap = queryParentDepIdMap(sysUserDeparts);
            // 现在我们需要将这些子 depId 合并到它们的上级 depId 中
            for (Map.Entry<String, Integer> entry : depIdCountMap.entrySet()) {
                String childDepId = entry.getKey();
                Integer count = entry.getValue();
                // 获取上级 depId
                String parentDepId = childToParentDepIdMap.getOrDefault(childDepId, childDepId);
                // 将人数累加到上级 depId
                parentDepIdCountMap.merge(parentDepId, count, Integer::sum);
            }
            depIdCountMap.clear();
            depIdCountMap.putAll(parentDepIdCountMap);
            sysStatisticsVO.setOrgColumnName("各企业人数");
        } else {
            sysStatisticsVO.setOrgColumnName("各部门人数");
        }
        Integer totalSum = depIdCountMap.values().stream()
                .filter(Objects::nonNull)
                .mapToInt(Integer::intValue)
                .sum();
        sysStatisticsVO.setDepartUserCount(totalSum);
        Integer diffCount = departCount - totalSum;
        sysStatisticsVO.setMemberDiffCount(diffCount < 0 ? 0 : diffCount);

        departMap.forEach((d, sysDepart) -> {
            String departName = sysDepart.getDepartName();
            Integer member = sysDepart.getMember();
            Integer count = 0;
            if (depIdCountMap.containsKey(d)) {
                count = depIdCountMap.get(d);
            }
            OrgColumnVo orgColumnVo = OrgColumnVo.builder()
                    .departName(departName)
                    .userCount(count)
                    .memberCount(member == null ? 0 : member)
                    .build();
            orgColumnVoList.add(orgColumnVo);
        });
        sysStatisticsVO.setOrgColumnList(orgColumnVoList);

        List<String> userIdList = sysUserDeparts.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
        if (userIdList.size() > 0) {
            // 统计各学历人数
            LambdaQueryWrapper<UserInfoEntity> queryUserInfoCount = new LambdaQueryWrapper<>();
            queryUserInfoCount.in(UserInfoEntity::getUserId, userIdList);
            List<UserInfoEntity> userInfoEntities = userInfoMapper.selectList(queryUserInfoCount);

            Map<String, Long> fullTimeEducationCountMap = userInfoEntities.stream()
                    .collect(Collectors.groupingBy(UserInfoEntity::getFullTimeEducation, Collectors.counting()));

            List<NameValueVo> educationCountList = fullTimeEducationCountMap.entrySet().stream()
                    .map(entry -> new NameValueVo(entry.getKey(), entry.getValue()))
                    .collect(Collectors.toList());
            sysStatisticsVO.setFullTimeEducationCount(educationCountList);
        }

        return sysStatisticsVO;
    }

    private List<SysDepart> queryCurrentAndChildByDepId(String depId) {
        List<SysDepart> sysDeparts = sysDepartMapper.queryCurrentAndChildByDepId(depId);
        return sysDeparts;
    }


    /**
     * 查询部门占员额的人数
     *
     * @param depId
     * @param depIdList
     */
    public List<SysUserDepart> querySysUserDepartList(String depId, List<String> depIdList) {
        // 全部可用用户id
        List<String> userIdList = sysUserMapper.queryUserId();
        if (CollectionUtils.isEmpty(userIdList)) {
            return null;
        }
        LambdaQueryWrapper<SysUserDepart> querySysUserDepart = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(depId)) {
            querySysUserDepart.in(SysUserDepart::getDepId, depIdList);
        }
        // 查询占员额的人数
        querySysUserDepart.eq(SysUserDepart::getMemberFlag, 1);
        querySysUserDepart.in(SysUserDepart::getUserId, userIdList);
        List<SysUserDepart> sysUserDepartList = sysUserDepartMapper.selectList(querySysUserDepart);
        return sysUserDepartList;
    }


    /**
     * 传入depId 如果depId为空 返回各企业 SysDepart
     * 如果depId不为空 返回内设机构加各领导层 SysDepart
     *
     * @Date: 2024-09-02 09:43
     */
    private List<SysDepart> queryOrgDepart(String depId) {
        List<SysDepart> sysDeparts = sysDepartMapper.queryIndexSysDepart(depId);
        return sysDeparts;
    }


    private SysDepart queryParentDepIdByDepId(String depId, Map<String, SysDepart> sysDepartMap) {
        if (StringUtils.isBlank(depId)) {
            throw new JeecgBootException("当前用户的org_code为空，请检查。");
        }

        // 获取当前部门
        SysDepart depart = sysDepartMap.get(depId);
        if (depart == null) {
            throw new JeecgBootException("部门未找到，请检查ID。");
        }

        // 如果当前部门的orgCategory为1，则返回当前部门的ID
        if (StringUtils.equals(depart.getOrgCategory(), "1")) {
            return depart;
        }

        // 否则，继续递归查找父级部门
        if (StringUtils.isNotBlank(depart.getParentId())) {
            return queryParentDepIdByDepId(depart.getParentId(), sysDepartMap);
        }
        // 如果没有找到符合条件的部门
        return null;
    }


    /**
     * 根据传入部门信息，返回部门对应的公司id
     *
     * @param sysUserDepartList
     */
    private Map<String, String> queryParentDepIdMap(List<SysUserDepart> sysUserDepartList) {
        Map<String, String> childToParentDepIdMap = new HashMap<>();
        // 所有部门信息
        List<SysDepart> departList = sysDepartMapper.queryDepartList();
        Map<String, SysDepart> sysDepartMap = departList.stream().collect(Collectors.toMap(SysDepart::getId, Function.identity()));
        for (SysUserDepart userDepart : sysUserDepartList) {
            SysDepart sysDepart = this.queryParentDepIdByDepId(userDepart.getDepId(), sysDepartMap);
            if (sysDepart != null) {
                childToParentDepIdMap.put(userDepart.getDepId(), sysDepart.getId());
            }
        }
        return childToParentDepIdMap;
    }
}
